package net.oschina.victor.liu.lemon.common.shiro;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import net.oschina.victor.liu.lemon.entity.User;
import net.oschina.victor.liu.lemon.service.UserService;

/**
 * 通过用户名密码进行身份认证及授权时使用的领域类
 * 
 * @author Victor
 *
 */
public class UsernamePasswordRealm extends AuthorizingRealm {

	private Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	private UserService userService;

	/**
	 * 对登录的用户进行授权，此处需要使用较为复杂的算法解决
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

		for (Object principal : principals) {
			String username = (String) principal;
			System.out.println("username:" + username);

			SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
			authorizationInfo.setRoles(userService.findRoles(username));
			authorizationInfo.setStringPermissions(userService.findPermissions(username));

			// 查询所有角色
			// 查询所有权限
			// a.用户权限
			// b.角色权限
			// TODO 先通过数据库的方式访问，成功后在进行缓存的调试
		}

		return null;
	}

	/**
	 * 登录验证功能，根据用户名、密码进行验证
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authToken) throws AuthenticationException {

		System.out.println("系统校验");
		// 1、判断是否使用的用户名密码进行认证，如果不是用户名密码认证方式则跳过此认证方法
		UsernamePasswordToken token = null;
		if (authToken instanceof UsernamePasswordToken) {
			token = (UsernamePasswordToken) authToken;
		} else {
			return null;
		}

		// int activeSessionSize =
		// getSystemService().getSessionDao().getActiveSessions(false).size();
		// if (logger.isDebugEnabled()) {
		// logger.debug("login submit, active session size: {}, username: {}",
		// activeSessionSize, token.getUsername());
		// }

		// //2、校验登录验证码
		// if (LoginController.isValidateCodeLogin(token.getUsername(), false,
		// false)) {
		// Session session = UserUtils.getSession();
		// String code = (String)
		// session.getAttribute(ValidateCodeServlet.VALIDATE_CODE);
		// if (token.getCaptcha() == null ||
		// !token.getCaptcha().toUpperCase().equals(code)) {
		// throw new AuthenticationException("msg:验证码错误, 请重试.");
		// }
		// }

		// 校验用户名密码
		User user = userService.getUser(token.getUsername());
		if (user == null) {
			throw new UnknownAccountException();// 没找到帐号
		}
		// System.out.println("user.getCredentialsSalt()" +
		// user.getCredentialsSalt());
		// System.out.println("user.getCredentialsSalt()" +
		// ByteSource.Util.bytes(user.getCredentialsSalt()));
		// if (Boolean.FALSE.equals(user.getAvailable())) { throw new
		// LockedAccountException(); // 帐号锁定 }

		// 交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配，如果觉得人家的不好可以自定义实现
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(), // 用户名
				user.getPassword(), // 密码
				ByteSource.Util.bytes(user.getCredentialsSalt()), // salt=username+salt
				getName() // realm name
		);
		return authenticationInfo;
	}

}
